﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.AvalonEdit;
using System.Windows;
using Microsoft.Xaml.Behaviors;

namespace WpfApp1.Helpers
{
    public sealed class AvalonEditBehaviour : Behavior<TextEditor>
    {
        //依赖属性绑定
        public static readonly DependencyProperty CodeTextProperty =
        DependencyProperty.Register("CodeText",
                                    typeof(string),
                                    typeof(AvalonEditBehaviour),
                                    new FrameworkPropertyMetadata(default(string),
                                                                  FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                                                                  PropertyChangedCallback));

        public string CodeText
        {
            get => (string)GetValue(CodeTextProperty);
            set => SetValue(CodeTextProperty, value);
        }

        protected override void OnAttached()
        {
            base.OnAttached();
            if (AssociatedObject != null)
                AssociatedObject.TextChanged += AssociatedObjectOnTextChanged;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            if (AssociatedObject != null)
                AssociatedObject.TextChanged -= AssociatedObjectOnTextChanged;
        }

        private void AssociatedObjectOnTextChanged(object? sender, EventArgs eventArgs)
        {
            if (sender is TextEditor textEditor)
            {
                if (textEditor.Document != null)
                    CodeText = textEditor.Document.Text;
            }
        }

        private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var behavior = dependencyObject as AvalonEditBehaviour;
            if (behavior?.AssociatedObject != null)
            {
                var editor = behavior.AssociatedObject;
                if (editor.Document != null)
                {
                    var caretOffset = editor.CaretOffset;
                    editor.Document.Text = dependencyPropertyChangedEventArgs.NewValue.ToString();
                    if (caretOffset <= editor.Document.Text?.Length) editor.CaretOffset = caretOffset;
                }
            }
        }
    }
}